#define _GNU_SOURCE  // 启用GNU扩展，包括strdup函数
#include "server_functions.h"
#include <errno.h>
#include <sys/stat.h>  // 用于创建目录

// 定义全局配置变量
Config config = {
    .port = SERVER_PORT,
    .document_root = ".",
    .max_connections = 10
};

// 解析HTTP请求行
void parse_http_request(char *request, char **method, char **path, char **query) {
    if (!request || !method || !path || !query) return;

    char *line_end = strstr(request, "\r\n");
    if (!line_end) return;

    // 复制请求行
    char *request_line = (char *)malloc(line_end - request + 1);
    if (!request_line) return;
    strncpy(request_line, request, line_end - request);
    request_line[line_end - request] = '\0';

    // 解析方法
    char *method_start = request_line;
    char *method_end = strchr(method_start, ' ');
    if (!method_end) {
        free(request_line);
        return;
    }
    *method_end = '\0';
    *method = strdup(method_start);

    // 解析路径和查询参数
    char *path_start = method_end + 1;
    char *path_end = strchr(path_start, ' ');
    if (!path_end) {
        free(request_line);
        free(*method);
        return;
    }
    *path_end = '\0';

    char *query_start = strchr(path_start, '?');
    if (query_start) {
        *query_start = '\0';
        *path = strdup(path_start);
        *query = strdup(query_start + 1);
    } else {
        *path = strdup(path_start);
        *query = strdup("");
    }

    free(request_line);
}

// 处理GET请求
void handle_get_request(SOCKET client_socket, char *path, char *query) {
    if (!path) return;

    // 特殊路径处理
    if (strcmp(path, "/version") == 0) {
        char json_response[256];
        sprintf(json_response, "{\"version\":\"%s\"}", SERVER_VERSION);
        send_json_response(client_socket, json_response, 200);
        return;
    }
    
    if (strcmp(path, "/files") == 0) {
        list_directory(client_socket, config.document_root);
        return;
    }
    
    if (strcmp(path, "/config") == 0) {
        char json_response[512];
        sprintf(json_response, "{\"port\":%d,\"document_root\":\"%s\",\"max_connections\":%d}", 
                config.port, config.document_root, config.max_connections);
        send_json_response(client_socket, json_response, 200);
        return;
    }
    
    // 返回当前工作目录
    if (strcmp(path, "/pwd") == 0) {
        char cwd[1024];
        if (getcwd(cwd, sizeof(cwd)) != NULL) {
            char json_response[1024 + 32];
            sprintf(json_response, "{\"current_working_directory\":\"%s\"}", cwd);
            send_json_response(client_socket, json_response, 200);
        } else {
            send_json_response(client_socket, 
                "{\"error\":\"Failed to get current working directory\"}", 500);
        }
        return;
    }
    
    // 处理CGI请求
    if (strstr(path, "/cgi/") == path) {
        int param_count = 0;
        Param *params = parse_query_string(query, &param_count);
        handle_cgi(client_socket, path, params, param_count);
        free_params(params, param_count);
        return;
    }

    // 构建文件路径
    char file_path[1024];
    if (strcmp(path, "/") == 0) {
        sprintf(file_path, "%s/index.html", config.document_root);
    } else {
        sprintf(file_path, "%s%s", config.document_root, path);
    }

    // 发送文件
    send_file(client_socket, file_path);
}

// 处理POST请求
void handle_post_request(SOCKET client_socket, char *path, char *content) {
    printf("[DEBUG] POST request received\n");
    printf("[DEBUG] Path: %s\n", path ? path : "NULL");
    printf("[DEBUG] Content: %s\n", content ? content : "NULL");
    
    if (!path || !content) {
        printf("[ERROR] Invalid path or content\n");
        return;
    }

    // 处理CGI设置参数请求
    if (strcmp(path, "/cgi/set_config") == 0) {
        printf("[DEBUG] Processing set_config request\n");
        int param_count = 0;
        Param *params = parse_query_string(content, &param_count);
        printf("[DEBUG] Parsed %d parameters\n", param_count);
        
        // 更新配置
        for (int i = 0; i < param_count; i++) {
            printf("[DEBUG] Parameter %d: %s = %s\n", i, params[i].name, params[i].value);
            if (strcmp(params[i].name, "port") == 0) {
                int old_port = config.port;
                config.port = atoi(params[i].value);
                printf("[DEBUG] Port updated: %d -> %d\n", old_port, config.port);
            } else if (strcmp(params[i].name, "document_root") == 0) {
                printf("[DEBUG] Document root updated: %s -> %s\n", config.document_root, params[i].value);
                free(config.document_root);
                config.document_root = strdup(params[i].value);
            } else if (strcmp(params[i].name, "max_connections") == 0) {
                int old_max = config.max_connections;
                config.max_connections = atoi(params[i].value);
                printf("[DEBUG] Max connections updated: %d -> %d\n", old_max, config.max_connections);
            }
        }
        
        // 返回新配置
        char json_response[512];
        sprintf(json_response, "{\"success\":true,\"config\":{\"port\":%d,\"document_root\":\"%s\",\"max_connections\":%d}}", 
                config.port, config.document_root, config.max_connections);
        printf("[DEBUG] Sending config response: %s\n", json_response);
        send_json_response(client_socket, json_response, 200);
        
        free_params(params, param_count);
        return;
    } 
    // 处理设置时间请求
    else if (strcmp(path, "/cgi/set_time") == 0) {
        printf("[DEBUG] Processing set_time request\n");
        int param_count = 0;
        Param *params = parse_query_string(content, &param_count);
        printf("[DEBUG] Parsed %d parameters for time setting\n", param_count);
        
        // 获取时间参数
        char *time_str = NULL;
        
        for (int i = 0; i < param_count; i++) {
            printf("[DEBUG] Time parameter %d: %s = %s\n", i, params[i].name, params[i].value);
            if (strcmp(params[i].name, "time") == 0) {
                time_str = params[i].value;
                printf("[DEBUG] Found time parameter: %s\n", time_str);
                break;
            }
        }
        
        // 验证时间参数是否存在
        if (!time_str) {
            printf("[ERROR] Time parameter not found\n");
            send_json_response(client_socket, 
                "{\"success\":false,\"error\":\"Time parameter is required. Format: YYYY-MM-DD HH:MM:SS\"}", 400);
            free_params(params, param_count);
            return;
        }
        
        // 解析时间字符串 (格式: YYYY-MM-DD HH:MM:SS)
        struct tm time_info = {0};
        printf("[DEBUG] Parsing time string: %s\n", time_str);
        if (sscanf(time_str, "%d-%d-%d %d:%d:%d", 
                   &time_info.tm_year, &time_info.tm_mon, &time_info.tm_mday, 
                   &time_info.tm_hour, &time_info.tm_min, &time_info.tm_sec) != 6) {
            printf("[ERROR] Failed to parse time format\n");
            send_json_response(client_socket, 
                "{\"success\":false,\"error\":\"Invalid time format. Use: YYYY-MM-DD HH:MM:SS\"}", 400);
            free_params(params, param_count);
            return;
        }
        printf("[DEBUG] Parsed time: %04d-%02d-%02d %02d:%02d:%02d\n", 
               time_info.tm_year, time_info.tm_mon, time_info.tm_mday,
               time_info.tm_hour, time_info.tm_min, time_info.tm_sec);
        
        // 验证时间参数是否有效
        if (time_info.tm_year < 2000 || time_info.tm_mon < 1 || time_info.tm_mon > 12 || 
            time_info.tm_mday < 1 || time_info.tm_mday > 31 || 
            time_info.tm_hour < 0 || time_info.tm_hour > 23 || 
            time_info.tm_min < 0 || time_info.tm_min > 59 || 
            time_info.tm_sec < 0 || time_info.tm_sec > 59) {
            printf("[ERROR] Invalid time values detected\n");
            send_json_response(client_socket, 
                "{\"success\":false,\"error\":\"Invalid time values\"}", 400);
            free_params(params, param_count);
            return;
        }
        printf("[DEBUG] Time validation passed\n");
        
        // 调整tm_year和tm_mon的值 (tm_year是从1900年开始的年数，tm_mon是从0开始的月份)
        time_info.tm_year -= 1900;
        time_info.tm_mon -= 1;
        printf("[DEBUG] Adjusted time structure: year=%d, mon=%d\n", time_info.tm_year, time_info.tm_mon);
        
        // 转换为time_t
        time_t new_time = mktime(&time_info);
        if (new_time == -1) {
            printf("[ERROR] mktime() failed to convert time\n");
            send_json_response(client_socket, 
                "{\"success\":false,\"error\":\"Failed to convert time\"}", 500);
            free_params(params, param_count);
            return;
        }
        printf("[DEBUG] Converted to time_t: %ld\n", (long)new_time);
        
        // 设置系统时间
        struct timeval tv;
        tv.tv_sec = new_time;
        tv.tv_usec = 0;
        printf("[DEBUG] Attempting to set system time\n");
        
        if (settimeofday(&tv, NULL) == -1) {
            // 通常需要root权限才能设置系统时间
            printf("[ERROR] settimeofday() failed: %s\n", strerror(errno));
            send_json_response(client_socket, 
                "{\"success\":false,\"error\":\"Permission denied or system error\"}", 500);
            free_params(params, param_count);
            return;
        }
        printf("[DEBUG] System time set successfully\n");
        
        // 格式化返回的时间字符串
        char formatted_time[64];
        struct tm *set_time_info = localtime(&new_time);
        strftime(formatted_time, sizeof(formatted_time), "%Y-%m-%d %H:%M:%S", set_time_info);
        printf("[DEBUG] Formatted response time: %s\n", formatted_time);
        
        // 返回成功响应
        char json_response[256];
        sprintf(json_response, 
            "{\"success\":true,\"message\":\"System time updated successfully\",\"time\":\"%s\"}",
            formatted_time);
        printf("[DEBUG] Sending time response: %s\n", json_response);
        send_json_response(client_socket, json_response, 200);
        
        free_params(params, param_count);
        return;
    }

    // 默认返回404
    printf("[DEBUG] Unknown POST path: %s\n", path);
    send_json_response(client_socket, "{\"error\":\"Not found\"}", 404);
}

// 发送JSON响应
void send_json_response(SOCKET client_socket, const char *json, int status_code) {
    if (!json) return;

    const char *status_text;
    switch (status_code) {
        case 200: status_text = "OK";
        break;
        case 400: status_text = "Bad Request";
        break;
        case 404: status_text = "Not Found";
        break;
        case 500: status_text = "Internal Server Error";
        break;
        default: status_text = "Unknown Status";
    }

    char response[BUFFER_SIZE];
    int json_len = strlen(json);
    
    sprintf(response, "HTTP/1.1 %d %s\r\n", status_code, status_text);
    sprintf(response + strlen(response), "Content-Type: application/json\r\n");
    sprintf(response + strlen(response), "Content-Length: %d\r\n", json_len);
    sprintf(response + strlen(response), "Access-Control-Allow-Origin: *\r\n");
    sprintf(response + strlen(response), "Access-Control-Allow-Methods: GET, POST, OPTIONS\r\n");
    sprintf(response + strlen(response), "Access-Control-Allow-Headers: Content-Type\r\n");
    sprintf(response + strlen(response), "Connection: close\r\n");
    sprintf(response + strlen(response), "\r\n");
    sprintf(response + strlen(response), "%s", json);

    send(client_socket, response, strlen(response), 0);
}

// 发送文件
void send_file(SOCKET client_socket, const char *file_path) {
    if (!file_path) return;

    FILE *file = fopen(file_path, "rb");
    if (!file) {
        send_json_response(client_socket, "{\"error\":\"File not found\"}", 404);
        return;
    }

    // 获取文件大小
    fseek(file, 0, SEEK_END);
    long file_size = ftell(file);
    fseek(file, 0, SEEK_SET);

    // 读取文件内容
    char *file_content = (char *)malloc(file_size + 1);
    if (!file_content) {
        fclose(file);
        send_json_response(client_socket, "{\"error\":\"Memory allocation failed\"}", 500);
        return;
    }
    
    fread(file_content, 1, file_size, file);
    fclose(file);

    // 发送HTTP响应头
    const char *mime_type = get_mime_type(file_path);
    char header[1024];
    sprintf(header, "HTTP/1.1 200 OK\r\n");
    sprintf(header + strlen(header), "Content-Type: %s\r\n", mime_type);
    sprintf(header + strlen(header), "Content-Length: %ld\r\n", file_size);
    sprintf(header + strlen(header), "Access-Control-Allow-Origin: *\r\n");
    sprintf(header + strlen(header), "Access-Control-Allow-Methods: GET, POST, OPTIONS\r\n");
    sprintf(header + strlen(header), "Access-Control-Allow-Headers: Content-Type\r\n");
    sprintf(header + strlen(header), "Connection: close\r\n");
    sprintf(header + strlen(header), "\r\n");
    
    send(client_socket, header, strlen(header), 0);
    send(client_socket, file_content, file_size, 0);
    
    free(file_content);
}

// 列出目录内容
void list_directory(SOCKET client_socket, const char *dir_path) {
    if (!dir_path) return;

    DIR *dir = opendir(dir_path);
    if (!dir) {
        send_json_response(client_socket, "{\"error\":\"Cannot open directory\"}", 500);
        return;
    }

    struct dirent *entry;
    char json_response[4096] = "{\"files\":[";
    int first = 1;
    int file_count = 0;  // 文件计数器
    
    while ((entry = readdir(dir)) != NULL) {
        if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
            continue;
        }
        
        if (!first) {
            strcat(json_response, ",");
        }
        first = 0;
        file_count++;
        
        // 检查是文件还是目录
        char full_path[1024];
        sprintf(full_path, "%s/%s", dir_path, entry->d_name);
        
        struct stat st;
        stat(full_path, &st);
        
        // 为文件添加下载URL
        if (S_ISDIR(st.st_mode)) {
            sprintf(json_response + strlen(json_response), 
                    "{\"name\":\"%s\",\"type\":\"directory\",\"url\":\"/%s\"}", 
                    entry->d_name, entry->d_name);
        } else {
            sprintf(json_response + strlen(json_response), 
                    "{\"name\":\"%s\",\"type\":\"file\",\"size\":%ld,\"url\":\"/%s\"}", 
                    entry->d_name, st.st_size, entry->d_name);
        }
    }
    
    closedir(dir);
    // 在JSON响应中添加文件总数
    sprintf(json_response + strlen(json_response), "],\"file_count\":%d}", file_count);
    
    send_json_response(client_socket, json_response, 200);
}

// 创建上传目录
int create_upload_directory(void) {
    struct stat st = {0};
    
    if (stat(UPLOAD_DIR, &st) == -1) {
        if (mkdir(UPLOAD_DIR, 0755) == -1) {
            printf("[ERROR] Failed to create upload directory: %s\n", strerror(errno));
            return -1;
        }
        printf("[INFO] Created upload directory: %s\n", UPLOAD_DIR);
    }
    
    return 0;
}

// URL解码函数
char *url_decode(const char *str) {
    if (!str) return NULL;
    
    size_t len = strlen(str);
    char *decoded = malloc(len + 1);
    if (!decoded) return NULL;
    
    size_t i = 0, j = 0;
    while (i < len) {
        if (str[i] == '%' && i + 2 < len) {
            // 解码%XX格式
            int value;
            if (sscanf(str + i + 1, "%2x", &value) == 1) {
                decoded[j++] = (char)value;
                i += 3;
                continue;
            }
        }
        if (str[i] == '+') {
            decoded[j++] = ' ';  // +号转为空格
        } else {
            decoded[j++] = str[i];
        }
        i++;
    }
    decoded[j] = '\0';
    
    return decoded;
}

// 验证文件名安全性
int validate_filename(const char *filename) {
    if (!filename || strlen(filename) == 0) {
        return 0;
    }
    
    // 检查不允许的字符
    if (strstr(filename, "..") || strchr(filename, '/') || strchr(filename, '\\')) {
        return 0;
    }
    
    // 检查文件名长度
    if (strlen(filename) > 255) {
        return 0;
    }
    
    return 1;
}

// 提取boundary参数
char *extract_boundary(const char *content_type) {
    if (!content_type) return NULL;
    
    const char *boundary_start = strstr(content_type, "boundary=");
    if (!boundary_start) return NULL;
    
    boundary_start += 9; // 跳过"boundary="
    
    // 查找分界符的结束位置
    const char *boundary_end = strchr(boundary_start, ';');
    if (!boundary_end) {
        boundary_end = boundary_start + strlen(boundary_start);
    }
    
    size_t boundary_len = boundary_end - boundary_start;
    char *boundary = malloc(boundary_len + 3); // 加上"--"前缀
    if (!boundary) return NULL;
    
    sprintf(boundary, "--%.*s", (int)boundary_len, boundary_start);
    
    return boundary;
}

// 解析multipart/form-data数据
int parse_multipart_data(const char *content, const char *boundary, UploadFile *upload_file) {
    if (!content || !boundary || !upload_file) {
        return -1;
    }
    
    // 初始化结构体
    memset(upload_file, 0, sizeof(UploadFile));
    
    // 查找第一个boundary
    const char *start = strstr(content, boundary);
    if (!start) {
        printf("[ERROR] Boundary not found in content\n");
        return -1;
    }
    
    start += strlen(boundary);
    if (strncmp(start, "\r\n", 2) == 0) {
        start += 2;
    }
    
    // 查找头部信息结束位置
    const char *header_end = strstr(start, "\r\n\r\n");
    if (!header_end) {
        printf("[ERROR] Header end not found\n");
        return -1;
    }
    
    // 解析头部信息
    size_t header_len = header_end - start;
    char *header = malloc(header_len + 1);
    if (!header) return -1;
    
    strncpy(header, start, header_len);
    header[header_len] = '\0';
    
    // 提取文件名
    const char *filename_start = strstr(header, "filename=\"");
    if (filename_start) {
        filename_start += 10; // 跳过'filename="'
        const char *filename_end = strchr(filename_start, '"');
        if (filename_end) {
            size_t filename_len = filename_end - filename_start;
            upload_file->filename = malloc(filename_len + 1);
            if (upload_file->filename) {
                strncpy(upload_file->filename, filename_start, filename_len);
                upload_file->filename[filename_len] = '\0';
            }
        }
    }
    
    // 提取Content-Type
    const char *content_type_start = strstr(header, "Content-Type: ");
    if (content_type_start) {
        content_type_start += 14; // 跳过"Content-Type: "
        const char *content_type_end = strstr(content_type_start, "\r\n");
        if (content_type_end) {
            size_t content_type_len = content_type_end - content_type_start;
            upload_file->content_type = malloc(content_type_len + 1);
            if (upload_file->content_type) {
                strncpy(upload_file->content_type, content_type_start, content_type_len);
                upload_file->content_type[content_type_len] = '\0';
            }
        }
    }
    
    free(header);
    
    // 提取文件数据
    const char *data_start = header_end + 4; // 跳过"\r\n\r\n"
    
    // 查找下一个boundary或结束标记
    char end_boundary[256];
    sprintf(end_boundary, "\r\n%s", boundary);
    
    const char *data_end = strstr(data_start, end_boundary);
    if (!data_end) {
        // 尝试查找结束标记
        sprintf(end_boundary, "\r\n%s--", boundary);
        data_end = strstr(data_start, end_boundary);
        if (!data_end) {
            printf("[ERROR] Data end boundary not found\n");
            free_upload_file(upload_file);
            return -1;
        }
    }
    
    upload_file->data_size = data_end - data_start;
    upload_file->data = malloc(upload_file->data_size);
    if (!upload_file->data) {
        free_upload_file(upload_file);
        return -1;
    }
    
    memcpy(upload_file->data, data_start, upload_file->data_size);
    
    printf("[INFO] Parsed file: %s, size: %zu bytes, type: %s\n", 
           upload_file->filename ? upload_file->filename : "unknown",
           upload_file->data_size,
           upload_file->content_type ? upload_file->content_type : "unknown");
    
    return 0;
}

// 保存上传的文件
int save_uploaded_file(const UploadFile *upload_file, const char *save_path) {
    if (!upload_file || !save_path || !upload_file->data) {
        return -1;
    }
    
    FILE *file = fopen(save_path, "wb");
    if (!file) {
        printf("[ERROR] Failed to create file: %s - %s\n", save_path, strerror(errno));
        return -1;
    }
    
    size_t written = fwrite(upload_file->data, 1, upload_file->data_size, file);
    fclose(file);
    
    if (written != upload_file->data_size) {
        printf("[ERROR] Failed to write complete file data\n");
        unlink(save_path); // 删除不完整的文件
        return -1;
    }
    
    printf("[INFO] File saved successfully: %s (%zu bytes)\n", save_path, written);
    return 0;
}

// 释放上传文件结构体
void free_upload_file(UploadFile *upload_file) {
    if (!upload_file) return;
    
    free(upload_file->filename);
    free(upload_file->content_type);
    free(upload_file->data);
    
    memset(upload_file, 0, sizeof(UploadFile));
}

// 处理文件上传
void handle_file_upload(SOCKET client_socket, const char *content, const char *content_type) {
    printf("[DEBUG] Processing file upload\n");
    
    if (!content || !content_type) {
        send_json_response(client_socket, 
            "{\"success\":false,\"error\":\"Invalid upload data\"}", 400);
        return;
    }
    
    // 检查是否为multipart/form-data
    if (strstr(content_type, "multipart/form-data") == NULL) {
        send_json_response(client_socket, 
            "{\"success\":false,\"error\":\"Content-Type must be multipart/form-data\"}", 400);
        return;
    }
    
    // 创建上传目录
    if (create_upload_directory() != 0) {
        send_json_response(client_socket, 
            "{\"success\":false,\"error\":\"Failed to create upload directory\"}", 500);
        return;
    }
    
    // 提取boundary
    char *boundary = extract_boundary(content_type);
    if (!boundary) {
        send_json_response(client_socket, 
            "{\"success\":false,\"error\":\"Invalid boundary in Content-Type\"}", 400);
        return;
    }
    
    printf("[DEBUG] Extracted boundary: %s\n", boundary);
    
    // 解析上传数据
    UploadFile upload_file;
    if (parse_multipart_data(content, boundary, &upload_file) != 0) {
        free(boundary);
        send_json_response(client_socket, 
            "{\"success\":false,\"error\":\"Failed to parse upload data\"}", 400);
        return;
    }
    
    free(boundary);
    
    // 验证文件名
    if (!upload_file.filename || !validate_filename(upload_file.filename)) {
        free_upload_file(&upload_file);
        send_json_response(client_socket, 
            "{\"success\":false,\"error\":\"Invalid filename\"}", 400);
        return;
    }
    
    // 检查文件大小
    if (upload_file.data_size > MAX_UPLOAD_SIZE) {
        free_upload_file(&upload_file);
        char error_msg[256];
        sprintf(error_msg, 
            "{\"success\":false,\"error\":\"File too large (max %d bytes)\"}", 
            MAX_UPLOAD_SIZE);
        send_json_response(client_socket, error_msg, 400);
        return;
    }
    
    // 构建完整的文件路径
    char save_path[512];
    sprintf(save_path, "%s/%s", UPLOAD_DIR, upload_file.filename);
    
    // 保存文件
    if (save_uploaded_file(&upload_file, save_path) == 0) {
        // 成功响应
        char response[1024];
        sprintf(response, 
            "{"
            "\"success\":true,"
            "\"message\":\"File uploaded successfully\","
            "\"filename\":\"%s\","
            "\"size\":%zu,"
            "\"content_type\":\"%s\","
            "\"path\":\"%s\""
            "}",
            upload_file.filename,
            upload_file.data_size,
            upload_file.content_type ? upload_file.content_type : "unknown",
            save_path);
        
        send_json_response(client_socket, response, 200);
    } else {
        // 失败响应
        send_json_response(client_socket, 
            "{\"success\":false,\"error\":\"Failed to save file\"}", 500);
    }
    
    free_upload_file(&upload_file);
}